windows下C与C++执行cmd命令并实时获取输出

您所在的位置:网站首页 creadfile open_always windows下C与C++执行cmd命令并实时获取输出

windows下C与C++执行cmd命令并实时获取输出

2023-03-02 04:56| 来源: 网络整理| 查看: 265

1. 前言

在windows下一般会使用系统的cmd命令或者其他现成的一些命令行可执行程序来完成一些操作,比如:调用ping命令来测试网络是否畅通、调用ffmpeg命令进行视频转码等等。为了能在软件界面上有更好的交互输出,都需要将命令执行的过程拿到,进行处理,然后在界面上进行显示,让用户知道程序正在正常运行,下面就介绍几种输出的获取方式。

当前开发环境: win10 64位 IDE-MSVC2017

2. 使用_popen执行进程

通过_popen打开进程进行执行,通过fgets获取进程的输出。

#include #include int run_cmd(const char * cmd) { char MsgBuff[1024]; int MsgLen=1020; FILE * fp; if (cmd == NULL) { return -1; } if ((fp = _popen(cmd, "r")) == NULL) { return -2; } else { memset(MsgBuff, 0, MsgLen); //读取命令执行过程中的输出 while (fgets(MsgBuff, MsgLen, fp) != NULL) { printf("MsgBuff: %s\n", MsgBuff); } //关闭执行的进程 if(_pclose(fp) == -1) { return -3; } } return 0; } int main() { //const char *cmd = "ffmpeg -i D:\\123.mp4 -vf reverse D:\\out\\out1.mp4"; const char *cmd = "ping www.baidu.com"; int ret = 0; ret = run_cmd(cmd); printf("命令执行结果:%d\r\n",ret); getchar(); return 0; }3. CreateProcess重定向输出到文件

下面使用CreateProcess调用子进程运行,将输出保存在文件中,阻塞等待进程执行完毕。

int my_CreateProcess() { SECURITY_ATTRIBUTES sa; sa.nLength = sizeof(sa); sa.lpSecurityDescriptor = NULL; sa.bInheritHandle = TRUE; _unlink("D:/out/output.log"); HANDLE h = CreateFile((L"D:/out/output.log"), FILE_APPEND_DATA, FILE_SHARE_WRITE | FILE_SHARE_READ, &sa, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); PROCESS_INFORMATION pi; STARTUPINFO si; BOOL ret = FALSE; DWORD flags = CREATE_NO_WINDOW; ZeroMemory(&pi, sizeof(PROCESS_INFORMATION)); ZeroMemory(&si, sizeof(STARTUPINFO)); si.cb = sizeof(STARTUPINFO); si.dwFlags |= STARTF_USESTDHANDLES; si.hStdInput = NULL; si.hStdError = h; si.hStdOutput = h; TCHAR cmd[] = TEXT("ping www.baidu.com"); ret = CreateProcess(NULL, cmd, NULL, NULL, TRUE, flags, NULL, NULL, &si, &pi); if (ret) { WaitForSingleObject(pi.hProcess, INFINITE); printf("执行成功....\n"); CloseHandle(pi.hProcess); CloseHandle(pi.hThread); //关闭文件 CloseHandle(h); return 0; } //关闭文件 CloseHandle(h); printf("执行失败....\n"); return -1; }4. CreateProcess重定向输出到管道

为了能实时获取CreateProcess打开进程运行时实时输出的结果,可以将CreateProcess的输出重定向到管道文件,CreateProcess将数据写到管道的写端,在父进程里再从管道的读端就能实时读取数据。

int my_CreateProcess() { BOOL run_pipe; PROCESS_INFORMATION pi; STARTUPINFO si; BOOL ret = FALSE; DWORD flags = CREATE_NO_WINDOW; _unlink("D:/out/output.log"); char pBuffer[210]; SECURITY_ATTRIBUTES sa; sa.nLength = sizeof(SECURITY_ATTRIBUTES); sa.lpSecurityDescriptor = NULL; sa.bInheritHandle = TRUE; HANDLE hReadPipe, hWritePipe; run_pipe=CreatePipe(&hReadPipe, &hWritePipe, &sa, 0); printf("run_pipe=%d\n", run_pipe); ZeroMemory(&pi, sizeof(PROCESS_INFORMATION)); ZeroMemory(&si, sizeof(STARTUPINFO)); si.cb = sizeof(STARTUPINFO); si.dwFlags |= STARTF_USESTDHANDLES; si.hStdInput = NULL; si.hStdError = hWritePipe; si.hStdOutput = hWritePipe; TCHAR cmd[] = TEXT("ffmpeg -i D:\\123.mp4 -vf reverse D:\\out\\out1.mp4"); ret = CreateProcess(NULL, cmd, NULL, NULL, TRUE, flags, NULL, NULL, &si, &pi); if (ret) { while (true) { DWORD ExitCode = 0; //判断进程是否执行结束 GetExitCodeProcess(pi.hProcess, &ExitCode); if (ExitCode == STILL_ACTIVE) //正在运行 { DWORD RSize=0; BOOL run_s=0; run_s =ReadFile(hReadPipe, pBuffer,200,&RSize,NULL); pBuffer[RSize] = '\0'; printf("返回结果:%d,%d,%s\n", run_s, RSize, pBuffer); } else //结束 { printf("执行完毕...\n"); break; } } //WaitForSingleObject(pi.hProcess, INFINITE); printf("执行成功....\n"); CloseHandle(pi.hProcess); CloseHandle(pi.hThread); return 0; } printf("执行失败....\n"); return -1; }


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3